package cn.iocoder.yudao.module.member.service.activation;

import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.module.member.controller.admin.activation.userVo.UserActivationPageReqVO;
import cn.iocoder.yudao.module.member.controller.admin.activation.userVo.UserActivationSaveReqVO;
import cn.iocoder.yudao.module.member.dal.dataobject.activation.ActivationDO;
import cn.iocoder.yudao.module.member.dal.dataobject.invitationcode.InvitationCodeDO;
import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO;
import cn.iocoder.yudao.module.member.dal.mysql.activation.UserActivationMapper;
import cn.iocoder.yudao.module.member.dal.mysql.invitationcode.InvitationCodeMapper;
import cn.iocoder.yudao.module.member.dal.mysql.user.MemberUserMapper;
import cn.iocoder.yudao.module.member.service.invitationcode.InvitationCodeService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;

import cn.iocoder.yudao.module.member.dal.dataobject.activation.UserActivationDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.member.dal.mysql.activation.ActivationMapper;

import javax.annotation.Resource;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.*;

/**
 * 我的激活码 Service 实现类
 *
 * @author Alan
 */
@Service
@Validated
public class UserActivationServiceImpl implements UserActivationService {
    @Resource
    private InvitationCodeMapper invitationCodeMapper;
    @Resource
    private UserActivationMapper userActivationMapper;
    @Resource
    private ActivationMapper activationMapper;
    @Resource
    private MemberUserMapper memberUserMapper;


    @Override
    public Long createActivation(UserActivationSaveReqVO createReqVO) {
        List<Long> userIds = createReqVO.getUserIds();
        for (Long le:userIds){
            ActivationDO activationDO = activationMapper.selectOne(new LambdaQueryWrapper<ActivationDO>()
                    .eq(ActivationDO::getActivationCode, createReqVO.getActivationCode()));
            validateTimes(activationDO.getBeginTime(),activationDO.getEndTime());
            UserActivationDO activationDO1 = userActivationMapper.selectOne(new LambdaQueryWrapper<UserActivationDO>()
                    .eq(UserActivationDO::getActivationCode, createReqVO.getActivationCode())
                    .eq(UserActivationDO::getUserId, le)
            );
            MemberUserDO memberUserDO = memberUserMapper.selectById(le);
            if(Objects.nonNull(activationDO1)){
                throw exception(new ErrorCode(121213,"该用户"+memberUserDO.getNickname()+"已有此激活码,请勿重复发送"));
            }
            // 插入
            UserActivationDO activation = BeanUtils.toBean(createReqVO, UserActivationDO.class);
            activation.setUserId(le);
            userActivationMapper.insert(activation);
        }
        // 返回
        return 1L;
    }
    public void validateTimes(LocalDateTime beginTime, LocalDateTime endTime) {
        LocalDateTime now = LocalDateTime.now();
        if (endTime == null) {
            throw exception(new ErrorCode(121213,"结束时间不能为空"));
        }

        if (endTime.isBefore(now)) {
            throw exception(new ErrorCode(121213,"结束时间不能小于当前时间"));
        }

        if (beginTime != null && beginTime.isAfter(endTime)) {
            throw exception(new ErrorCode(121213,"开始时间不能大于结束时间"));
        }
    }

    @Override
    public void updateActivation(UserActivationSaveReqVO updateReqVO) {
        // 校验存在
        validateActivationExists(updateReqVO.getId());
        // 更新
        UserActivationDO updateObj = BeanUtils.toBean(updateReqVO, UserActivationDO.class);
        userActivationMapper.updateById(updateObj);
    }

    @Override
    public void deleteActivation(Long id) {
        // 校验存在
        validateActivationExists(id);
        // 删除
        userActivationMapper.deleteById(id);
    }

    private void validateActivationExists(Long id) {
        if (userActivationMapper.selectById(id) == null) {
            throw exception(ACTIVATION_NOT_EXISTS);
        }
    }

    @Override
    public UserActivationDO getActivation(Long id) {
        return userActivationMapper.selectById(id);
    }

    @Override
    public PageResult<UserActivationDO> getActivationPage(UserActivationPageReqVO pageReqVO) {
        return userActivationMapper.selectPage(pageReqVO);
    }

    /**
     * 校验激活码是否给用户
     * 校验激活码是否存在
     *
     * @param userActivationSaveReqVO
     */
    @Override
    public void createActivationCode(UserActivationSaveReqVO userActivationSaveReqVO) {
        List<InvitationCodeDO> userActivationDOS = invitationCodeMapper.selectList(new LambdaQueryWrapper<InvitationCodeDO>());
        Boolean flag = false;
        for (InvitationCodeDO activationDO:userActivationDOS){
            if (userActivationSaveReqVO.getActivationCode().equals(activationDO.getNumber())){
                flag = true;
            }
        }
        if (flag){
            InvitationCodeDO activationDO = invitationCodeMapper.selectOne(new LambdaQueryWrapper<InvitationCodeDO>()
                    .eq(InvitationCodeDO::getNumber, userActivationSaveReqVO.getActivationCode()));
            if (Objects.isNull(activationDO)){
                throw exception(ACTIVATION_NOT);
            }
            UserActivationDO userActivationDO = userActivationMapper.selectOne(new LambdaQueryWrapper<UserActivationDO>()
                    .eq(UserActivationDO::getUserId, userActivationSaveReqVO.getUserId())
                    .eq(UserActivationDO::getActivationCode, userActivationSaveReqVO.getActivationCode())
            );
            if (Objects.nonNull(userActivationDO)){
                throw exception(ACTIVATION_NOT_1);
            }
            if (activationDO.getRemainingNumber() == 0) {
                throw exception(ACTIVATION_NOT_2);
            }

            MemberUserDO memberUserDO = memberUserMapper.selectById(userActivationSaveReqVO.getUserId());
            String effectiveDays = activationDO.getEffectiveDays();
            //如果已经是会员，则增加时间
            LocalDateTime[] localDateTimes = generateTimeRange(Integer.valueOf(effectiveDays));
            if (memberUserDO.getIsMember()){
                memberUserDO.setMemberExpireDate(DateUtils.resultTime(localDateTimes[0],localDateTimes[1], memberUserDO.getMemberExpireDate()));
            } else {
                //设置成会员
                memberUserDO.setIsMember(true);
                memberUserDO.setMemberExpireDate(localDateTimes[1]);
                memberUserDO.setMemberOpenDate(localDateTimes[0]);
            }
            memberUserMapper.updateById(memberUserDO);
            activationDO.setRemainingNumber(activationDO.getRemainingNumber()-1);
            if (activationDO.getRemainingNumber() == 0) {
                activationDO.setStatus("2");
            }
            invitationCodeMapper.updateById(activationDO);
            // 插入
            UserActivationDO activation = new UserActivationDO();
            activation.setUserId(userActivationSaveReqVO.getUserId());
            activation.setActivationCode(userActivationSaveReqVO.getActivationCode());
            userActivationMapper.insert(activation);
        } else {
            throw exception(MY_ACTIVATION_NOT);
        }
    }
    /**
     * 根据有效天数生成开始时间和结束时间
     *
     * @param validDays 有效天数，例如 10
     * @return 包含开始时间和结束时间的数组 [startTime, endTime]
     */
    public static LocalDateTime[] generateTimeRange(int validDays) {
        LocalDateTime startTime = LocalDateTime.now(); // 当前时间作为开始时间
        LocalDateTime endTime = startTime.plusDays(validDays); // 开始时间 + 有效天数

        return new LocalDateTime[]{startTime, endTime};
    }
}